热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用字|多种_c++数组初始化与删除用法大全

篇首语:本文由编程笔记#小编为大家整理,主要介绍了c++数组初始化与删除用法大全相关的知识,希望对你有一定的参考价值。0.前言大家公认的c&#

篇首语:本文由编程笔记#小编为大家整理,主要介绍了c++数组初始化与删除用法大全相关的知识,希望对你有一定的参考价值。



0.前言

大家公认的c++学习曲线比较陡峭,在我看来很重要一个原因就是c++语法比较灵活,要实现某个功能可能有好多种写法都能实现,所以很多时候就容易给大家带来困扰,搞不清楚为什么要这么写,或者这么写到底为啥,跟我平时写的为什么不一样。比如我们常用的数组,其初始化/删除就有非常多的方式,而且这些方式也比较混乱,没有特别的规律,很容易把人给直接绕晕圈了。下面我们来针对数组的初始化/删除方式做一个总结,如果有不对或者不全的地方,大家可以进行指正补充。


1.静态初始化

比较常见的初始化方式为静态初始化。下面我们来看实例

void static_init()
int a[5] = 1, 2, 3, 4, 5;
int b[3] = 1;
int c[5] = 1,;
const int n = 3;
int d[n] = 1, 2, 3;
for(int i&#61;0; i<sizeof(a)/sizeof(a[0]); i&#43;&#43;) cout<<a[i]<<" ";
cout<<endl;
for(int i&#61;0; i<sizeof(b)/sizeof(b[0]); i&#43;&#43;) cout<<b[i]<<" ";
cout<<endl;
for(int i&#61;0; i<sizeof(c)/sizeof(c[0]); i&#43;&#43;) cout<<c[i]<<" ";
cout<<endl;
for(int i&#61;0; i<sizeof(d)/sizeof(d[0]); i&#43;&#43;) cout<<d[i]<<" ";
cout<<endl;

1 2 3 4 5
1 0 0
1 0 0 0 0
1 2 3

上面的写法都是可以的。
数组a的初始化方法最为常见&#xff0c;直接用大括号初始化&#xff0c;大括号内的元素个数与数组声明时长度一致。
数组b大括号内的元素小于数组声明长度&#xff0c;不足的元素按0的默认值填充。
数组c的初始化方式与b类似。值得注意的是&#xff0c;在有些资料上会说c的方式有错误&#xff0c;但是经过本人实测&#xff0c;c的初始化方式是可以正常运行的&#xff0c;c&#43;&#43;版本为11。
数组d初始化时长度为变量n&#xff0c;注意此时必须要求n为const类型&#xff0c;否则会报错。

以下方式均为错误的。

// int n &#61; 3;
// int f[n] &#61; 1, 2, 3; error: variable-sized object may not be initialized
// int f[5] &#61; 1,,1; error: int [5](int)1, (), ()
// int f[5] &#61; 1, 2, 3, 4, 5, 6; error: excess elements in array initializer

2.字符串常量初始化字符数组

我们还经常用字符串常量初始化字符数组&#xff0c;这种用法特别常见。

void char_init()
char cs[8] &#61; "abcedfg";
char c2[5] &#61; "abc";
cout<<sizeof(cs)<<endl;
cout<<sizeof(c2)<<endl;

上面都是用一个字符串初始化字符数组&#xff0c;注意默认会在字符数组最后加上’\\0’。如果字符常量长度不够数组其他元素自动初始化为 ‘\\0’。


3.不指定长度初始化

void other_init()
int nums[] &#61; 1, 2, 3;
cout<<sizeof(nums)/sizeof(nums[0])<<endl;

上面的代码最终会输出3。初始化的时候&#xff0c;没有专门指定数组长度&#xff0c;但是列表内的元素个数会决定数组长度。


4.动态初始化数组

void dynamic_init()
int *a &#61; new int[3];
for(int i&#61;0; i<3; i&#43;&#43;) cout<<a[i]<<" ";
cout<<endl;
int *b &#61; new int[3]();
for(int i&#61;0; i<3; i&#43;&#43;) cout<<b[i]<<" ";
cout<<endl;
memset(b, 1, sizeof(int)*3);
for(int i&#61;0; i<3; i&#43;&#43;) cout<<b[i]<<" ";

上面代码输出&#xff1a;

0 0 0
0 0 0
16843009 16843009 16843009

动态初始化数组&#xff0c;则利用到了new关键字。使用new时&#xff0c;如果在运行阶段需要数组&#xff0c;则创建它&#xff1b;如果不需要&#xff0c;则不创建。还可以在程序运行时选择数组的长度。这被称为动态联编。意味着数组是在程序运行时创建的。这种数组叫做动态数组。在运行时确定数组的长度。

new出来的数据&#xff0c;需要用一个指针接收&#xff0c;返回的则是第一个元素的地址。
另外注意的是&#xff0c;new int[3]与new int3的效果一致&#xff0c;最后得到的都是默认值为0长度为3的一个整型数组。

另外我们需要注意的是&#xff0c;用memset函数时&#xff0c;进行设置时候&#xff0c;是一个字节一个字节进行设置。上面的写法&#xff0c;是将数组b的每个字节都设置为1&#xff0c;即0x01010101&#xff0c;换算成对应的十进制则为16843009。


5.删除动态数组

void dynamic_v2()
int *p &#61; new int[3];
p[0]&#61;0, p[1]&#61;1, p[2]&#61;2;
for(int i&#61;0; i<3; i&#43;&#43;) cout<<p[i]<<" ";
cout<<endl;
*p&#61;10, *(p&#43;1)&#61;11, *(p&#43;2)&#61;12;
for(int i&#61;0; i<3; i&#43;&#43;) cout<<p[i]<<" ";
cout<<endl;
*p&#61;20, *(&#43;&#43;p)&#61;21, *(&#43;&#43;p)&#61;22;
p-&#61;2; // 注意此时p已经指向了第三个元素&#xff0c;需要先减2回到起始位置
for(int i&#61;0; i<3; i&#43;&#43;) cout<<p[i]<<" ";
cout<<endl;
delete [] p;
for(int i&#61;0; i<3; i&#43;&#43;) cout<<p[i]<<" ";

0 1 2
10 11 12
20 21 22
20 21 22

使用new与delete时&#xff0c;我们需要注意以下事项&#xff1a;
1.delete不能释放不是new关键字分配的内存。
2.delete不能释放同一个内存两次。
3.如果是用new []为数组分配内存&#xff0c;则我们应该使用delete []释放。
4.对空指针进行delete是可以的&#xff0c;安全的。

上面代码需要注意的是&#xff1a;我们对p进行delete操作以后&#xff0c;似乎还能访问到原内存中的数据&#xff0c;这个就比较奇怪了&#xff0c;为什么会这样&#xff1f;

指针被delete以后&#xff0c;并没有被设置为NULL&#xff0c;此时delete只是把指针所指向的内存给释放掉&#xff0c;并没有把指针本身干掉&#xff0c;此时指针指向的是“垃圾”内存&#xff0c;这种指针成为悬挂指针(dangling pointer)。

所以一般我们delete完以后&#xff0c;可以将指针设置为NULL。


推荐阅读
author-avatar
Era_zhou
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有